package byteBuddy;

import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;

import java.lang.reflect.Method;

/**
 * 构造函数的拦截器
 *
 * @author BKJFSH
 */
public interface MethodInterceptor {

    /**
     * 获取方法的 matcher
     *
     * @return
     */
    ElementMatcher<? super MethodDescription> getMatcher();

    /**
     * 调用之前执行某些操作
     *
     * @param clazz        当前类名
     * @param thisObject   当前对象。如果是静态方法，则这个值是 null
     * @param method       当前被调用的方法
     * @param allArguments 方法的参数。参数可以被修改
     */
    default void beforeExecute(Class<?> clazz, Object thisObject, Method method, Object[] allArguments) {
    }

    /**
     * 当方法抛出异常时，调用这个方法
     *
     * @param clazz        当前类名
     * @param thisObject   当前对象。如果是静态方法，则这个值是 null
     * @param method       当前被调用的方法
     * @param allArguments 方法的参数。参数可以被修改
     * @param throwable
     */
    default void onException(Class<?> clazz, Object thisObject, Method method, Object[] allArguments, Throwable throwable) {
    }

    /**
     * 调用之后执行某些操作。即使方法报错，也会执行。相当于 finally
     *
     * @param clazz         当前类名
     * @param thisObject    当前对象。如果是静态方法，则这个值是 null
     * @param method        当前被调用的方法
     * @param allArguments  方法的参数。参数可以被修改
     * @param returnedValue 方法的返回值
     * @return 返回非 null 的值表示要替换方法的返回值。如果方法抛出了异常，那么返回值会被忽略
     */
    default Object onComplete(Class<?> clazz, Object thisObject, Method method, Object[] allArguments, Object returnedValue) {
        return returnedValue;
    }

}
